/* * 2012-3 Red Hat Inc. and/or its affiliates and other contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.overlord.gadgets.web.client.widgets; import java.util.HashMap; import java.util.Map; import org.overlord.gadgets.web.client.URLBuilder; import org.overlord.gadgets.web.client.auth.CurrentUser; import org.overlord.gadgets.web.client.util.RestfulInvoker; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.Response; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.InlineLabel; import com.google.gwt.user.client.ui.Widget; /** * @author: Jeff Yu * @date: 3/03/12 */ public class TabLayout extends Composite { interface TabLayoutUiBinder extends UiBinder<Widget, TabLayout>{} private static TabLayoutUiBinder uiBinder = GWT.create(TabLayoutUiBinder.class); private String id; private String promptId; @UiField UnorderedList tabsBar; @UiField FlowPanel tabsContent; @UiField DivElement tabs; @UiField DivElement promptDiv; private ListItem addTabAnchorItem; private CurrentUser currentUser; private Map<String, String> tabNames = new HashMap<String, String>(); private Map<String, String> indexIdMap = new HashMap<String, String>(); private static int index = 0; public TabLayout(CurrentUser user) { currentUser = user; id = "gadget-web-tabs"; initWidget(uiBinder.createAndBindUi(this)); tabs.setId(id); promptId = "gadget-web-tabs-prompt"; promptDiv.setId(promptId); } public void addTab(String pageId, String tabTitle, PortalLayout widget){ if (tabTitle == null || tabTitle.trim().length()==0) { tabTitle = "Tab-" + pageId; } String tabContentId = getTabContentId(pageId); tabNames.put(tabContentId, tabTitle); addTabTitle(tabTitle, tabContentId); widget.addClosingDiv(); FlowPanel theContent = new FlowPanel(); theContent.getElement().setId(tabContentId); theContent.add(widget); tabsContent.add(theContent); indexIdMap.put(String.valueOf(index), pageId); index ++; } public void setTabAnchor(Anchor anchor) { addTabAnchorItem = new ListItem(); addTabAnchorItem.add(anchor); tabsBar.add(addTabAnchorItem); } public void addTabAnchor() { tabsBar.add(addTabAnchorItem); } private void addTabTitle(String tabTitle, String tabContentId) { ListItem li = new ListItem(); li.getElement().setClassName("ui-state-default ui-corner-top"); Anchor anchor = new Anchor(); anchor.setHref("#" + tabContentId); anchor.setText(tabTitle); li.add(anchor); InlineLabel removeBtn = new InlineLabel(); removeBtn.setText("remove"); removeBtn.setStyleName("ui-icon ui-icon-close"); li.add(removeBtn); tabsBar.add(li); } public void insertTab(String pageId, String tabTitle, Widget widget) { if (tabTitle == null || tabTitle.trim().length()==0) { tabTitle = "Tab-" + pageId; } String tabContentId = getTabContentId(pageId); FlowPanel theContent = new FlowPanel(); theContent.getElement().setId(tabContentId); theContent.add(widget); tabsContent.add(theContent); int theIndex = tabNames.size(); tabNames.put(tabContentId, tabTitle); indexIdMap.put(String.valueOf(index), pageId); index = index + 1; tabsBar.remove(addTabAnchorItem); addNewTab(id, tabContentId, tabTitle, theIndex); tabsBar.add(addTabAnchorItem); updateUserCurrentPageId(Long.valueOf(pageId)); hidePrompt(promptId); } private String getTabContentId(String pageId) { return "tab-content-" + pageId; } @Override public void onAttach() { super.onAttach(); if (currentUser.getCurrentPage() == 0) { showPrompt(promptId); } else { hidePrompt(promptId); } } public void initializeTab() { initTabs(this, id); registerCloseEvent(this,id); } public void clearAllTabs(){ for(String contentId : tabNames.keySet()) { removeTab(id, contentId); } tabsBar.remove(addTabAnchorItem); destroyTab(id); index = 0; } private void setCurrentPage(String indexId) { String pageId = indexIdMap.get(indexId); long thePageId = Long.valueOf(pageId).longValue(); updateUserCurrentPageId(thePageId); } private void removePage(String indexId) { final String theIndexId = indexId; String pageId = indexIdMap.get(theIndexId); RestfulInvoker.invoke(RequestBuilder.POST, URLBuilder.getRemovePageURL(Long.valueOf(pageId).longValue()), null, new RestfulInvoker.Response() { @Override public void onResponseReceived(Request request, Response response) { indexIdMap.remove(theIndexId); decrementIndexes(Integer.valueOf(theIndexId)); index--; if (indexIdMap.size() == 0) { updateUserCurrentPageId(0); showPrompt(promptId); } } }); } /** * @param indexId */ protected void decrementIndexes(int indexId) { for (long idx = indexId; idx < index; idx++) { String theIdx = String.valueOf(idx); if (indexIdMap.containsKey(theIdx)) { String value = indexIdMap.remove(theIdx); indexIdMap.put(String.valueOf(idx - 1), value); } } } public void selectCurrentActiveTab() { String tabContentId = getTabContentId(String.valueOf(currentUser.getCurrentPage())); selectTab(id, tabContentId); } private void updateUserCurrentPageId(final long pageId) { RestfulInvoker.invoke(RequestBuilder.POST, URLBuilder.updateCurrentPageId(currentUser.getUserId(), pageId), null, new RestfulInvoker.Response() { @Override public void onResponseReceived(Request arg0, Response arg1) { currentUser.setCurrentPage(pageId); } }); } /** * JSNI methods */ private static native void initTabs(final TabLayout layout, String id) /*-{ $wnd.$('#'+id).tabs({ tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>remove</span></li>", select: function(event, ui) { layout.@org.overlord.gadgets.web.client.widgets.TabLayout::setCurrentPage(Ljava/lang/String;)(ui.index.toString()); } }); }-*/; private static native void selectTab(String id, String tabContentId) /*-{ var theTabs = $wnd.$('#'+id).tabs(); theTabs.tabs("select","#"+tabContentId); }-*/; private static native void addNewTab(String id, String tabContentId, String tabTitle, int index) /*-{ var theTabs = $wnd.$('#'+id).tabs(); theTabs.tabs("add", "#"+tabContentId, tabTitle, index); theTabs.tabs("select","#"+tabContentId); }-*/; private static native void removeTab(String id, String tabContentId) /*-{ var theTabs = $wnd.$('#'+id).tabs(); theTabs.tabs("remove","#"+tabContentId); }-*/; private static native void destroyTab(String id) /*-{ var theTabs = $wnd.$('#'+id).tabs(); theTabs.tabs("destroy"); }-*/; private static native void hidePrompt(String promptId) /*-{ $wnd.$('#'+promptId).hide(); }-*/; private static native void showPrompt(String promptId) /*-{ $wnd.$('#'+promptId).show(); }-*/; /** * TODO: This is a hack, somehow couldn't attach the click event to removetBtn; * if (confirm('Are you sure to delete the page?')) not working properly, it will trigger confirm window multiple times. **/ private static native void registerCloseEvent(final TabLayout layout, String id) /*-{ $wnd.$('#'+id + ' span.ui-icon-close').live('click', function(){ var theTabs = $wnd.$('#'+id).tabs(); var index = $wnd.$(this).parent().index(); if (index > -1 && confirm('Are you sure you want to delete this page?')) { layout.@org.overlord.gadgets.web.client.widgets.TabLayout::removePage(Ljava/lang/String;)(index.toString()); theTabs.tabs('remove', index); } }); }-*/; }